﻿using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Input;
using GalaSoft.MvvmLight.Command;
using ThreadingPrimeNumberSample.Core;

namespace ThreadingPrimeNumberSample
{
    public class PrimeMVVMViewModel : Notifier
    {
        #region Fields

        private readonly IPrimeEngine _primeEngine;
        private readonly IThreadProxy _threadProxy;

        #endregion Fields

        #region Properties

        private readonly int _guiThreadID;

        public int GuiThreadID
        {
            get { return _guiThreadID; }
        }

        private int _workerThreadID;

        public int WorkerThreadID
        {
            get { return _workerThreadID; }
            set
            {
                _workerThreadID = value;
                RaisePropertyChanged("WorkerThreadID");
            }
        }

        private int _primeNumber;

        public int PrimeNumber
        {
            get { return _primeNumber; }
            set
            {
                _primeNumber = value;
                RaisePropertyChanged("PrimeNumber");
            }
        }

        private string _buttonText;

        public string ButtonText
        {
            get { return _buttonText; }
            set
            {
                RaisePropertyChanged("ButtonText");
                _buttonText = value;
            }
        }

        public ICommand StartStopCommand
        {
            get { return new RelayCommand(StartStop); }
        }

        #endregion Properties

        #region Ctor

        public PrimeMVVMViewModel(IPrimeEngine primeEngine, 
            IThreadProxy threadProxy)
        {
            _primeEngine = primeEngine;
            _threadProxy = threadProxy;
            _primeEngine.PrimeFound += _primeEngine_PrimeFound;
            _guiThreadID = _threadProxy.GetCurrentThreadID();
            ButtonText = Strings.Start;
        }

        #endregion Ctor

        #region Event Handlers

        protected void _primeEngine_PrimeFound(object sender,
            PrimeFoundEventArgs e)
        {
            PrimeNumber = e.Prime;
        }

        #endregion Event Handlers

        #region Command Hanlders

        protected void StartStop()
        {
            if (_primeEngine.Continue)
            {
                _primeEngine.Continue = false;
                ButtonText = Strings.Stop;
            }
            else
            {
                ButtonText = Strings.Resume;
                _threadProxy.QueueUserWorkItem(CheckNextNumber);
            }
        }

        #endregion

        #region Helpers

        protected void CheckNextNumber(object state)
        {
            WorkerThreadID = _threadProxy.GetCurrentThreadID();
            _primeEngine.GetNextPrimeValue();
        }

        #endregion Helpers

        #region Dispose

        protected override void Dispose(bool isDisposing)
        {
            _primeEngine.PrimeFound -= _primeEngine_PrimeFound; 
            base.Dispose(isDisposing);
        }

        #endregion

    }
}